package jnpf.engine.custom.action;

import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import jnpf.engine.assembly.GlobalExPropertyDTO;
import jnpf.engine.assembly.UserTaskExPropertyDTO;
import jnpf.engine.assembly.prop.UserTaskAdvancedSettingDTO;
import jnpf.engine.custom.constants.BasicActivitiConstants;
import jnpf.engine.model.flowengine.shuntjson.childnode.TimeOutConfig;
import jnpf.engine.service.FlowTaskOperatorRecordService;
import jnpf.engine.util.SpringContextHolder;
import jnpf.util.JsonUtil;
import org.flowable.bpmn.model.BpmnModel;
import org.flowable.bpmn.model.Process;
import org.flowable.bpmn.model.UserTask;
import org.flowable.engine.RepositoryService;
import org.flowable.engine.RuntimeService;
import org.flowable.engine.TaskService;
import org.springframework.data.redis.connection.Message;
import org.springframework.data.redis.listener.KeyExpirationEventMessageListener;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.Map;

import static jnpf.engine.custom.constants.BasicActivitiConstants.exActivitiPrefixURL;
import static jnpf.engine.custom.constants.BasicActivitiConstants.extensionAttributeName;
import static jnpf.engine.custom.constants.GlobalProcessVariableConstants.BUSINESS_TITLE;
import static jnpf.engine.util.BpmnModelUtils.*;
import static jnpf.engine.util.BpmnModelUtils.getAttributeValueByTaskDefinitionKey;

/**
 * redis key 过期监听器
 */
@Component
public class RedisKeyExpirationListener extends KeyExpirationEventMessageListener {
    public RedisKeyExpirationListener(RedisMessageListenerContainer listenerContainer) {
        super(listenerContainer);
    }

    @Override
    public void onMessage(Message message, byte[] pattern) {
        String key = message.toString();
        if (StrUtil.startWith(key, BasicActivitiConstants.RECEIVE_TASK_TIME_KEY_PREFIX)) {
            String[] split = key.split("-");
            String processInstanceId = split[1];
            String executionId = split[2];
            String activityId = split[3];
            RuntimeService runtimeService = SpringContextHolder.getBean(RuntimeService.class);
            runtimeService.trigger(executionId);
        }

        if (StrUtil.startWith(key, BasicActivitiConstants.USER_TASK_TIME_KEY_PREFIX)) {
            TaskService taskService = SpringContextHolder.getBean(TaskService.class);
            RepositoryService repositoryService = SpringContextHolder.getBean(RepositoryService.class);
            RuntimeService runtimeService = SpringContextHolder.getBean(RuntimeService.class);
            FlowTaskOperatorRecordService flowTaskOperatorRecordService = SpringContextHolder.getBean(FlowTaskOperatorRecordService.class);


            String[] split = key.split("-");
            String processInstanceId = split[1];
            String taskId = split[2];
            String taskDefinitionKey = split[3];
            String processDefinitionId = split[4];

            BpmnModel bpmnModel = repositoryService.getBpmnModel(processDefinitionId);
            Process mainProcess = bpmnModel.getMainProcess();
            String property = getAttributeValueByTaskDefinitionKey(mainProcess, "", "global");
            GlobalExPropertyDTO exPropertyDTO = JSONObject.parseObject(property, new TypeReference<GlobalExPropertyDTO>() {
            });

            UserTask activity = (UserTask) mainProcess.getFlowElement(taskDefinitionKey);
            String taskProperty = activity.getAttributeValue(exActivitiPrefixURL, extensionAttributeName);
            UserTaskExPropertyDTO taskExPropertyDTO = JSONObject.parseObject(taskProperty, new TypeReference<UserTaskExPropertyDTO>() {
            });

            UserTaskAdvancedSettingDTO userTaskAdvancedSettingDTO = taskExPropertyDTO.getUserTaskAdvancedSettingDTO();
            TimeOutConfig timeOutConfig = userTaskAdvancedSettingDTO.getTimeOutConfig();
            String title = runtimeService.getVariable(processInstanceId, BUSINESS_TITLE, String.class);
/*            if (timeOutConfig != null) {
                if (timeOutConfig.getOn()) {
                    Integer handler = timeOutConfig.getHandler();
                    Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
                    FlowTaskOperatorRecordEntity flowTaskOperatorRecordEntity = new FlowTaskOperatorRecordEntity();
                    flowTaskOperatorRecordEntity.setId(RandomUtil.uuId());
                    flowTaskOperatorRecordEntity.setNodeCode(taskDefinitionKey);
                    flowTaskOperatorRecordEntity.setNodeName(task.getName());
                    flowTaskOperatorRecordEntity.setHandleStatus(FlowRecordEnum.audit.getCode());
                    flowTaskOperatorRecordEntity.setHandleId("admin");
                    flowTaskOperatorRecordEntity.setHandleName("管理员");
                    flowTaskOperatorRecordEntity.setHandleTime(new Date());
                    flowTaskOperatorRecordEntity.setHandleOpinion("任务超时 自动通过");
                    flowTaskOperatorRecordEntity.setOperatorId("admin");
                    flowTaskOperatorRecordEntity.setTaskNodeId(taskId);
                    flowTaskOperatorRecordEntity.setTaskId(processInstanceId);
                    flowTaskOperatorRecordEntity.setStatus(100);//随便
                    if (handler == 1) {
                        //保存
                        flowTaskOperatorRecordService.save(flowTaskOperatorRecordEntity);
                        taskService.complete(taskId);
                    }
                    //退回
                    else if (handler == 2) {
                        String rejectStep = userTaskAdvancedSettingDTO.getRejectStep();
                        flowTaskOperatorRecordEntity.setHandleStatus(FlowRecordEnum.reject.getCode());
                        flowTaskOperatorRecordEntity.setHandleOpinion("任务超时 自动拒绝");
                        flowTaskOperatorRecordService.save(flowTaskOperatorRecordEntity);
                        ArrayList<String> distinct = CollectionUtil.distinct(runtimeService.getActiveActivityIds(processInstanceId));
                        runtimeService.createChangeActivityStateBuilder()
                                .processInstanceId(processInstanceId)
                                .moveActivityIdsToSingleActivityId(distinct, rejectStep)
                                .changeState();
                    }
                    //
                    else {
                        //发送站内信 通知:
//                        List<IdentityLink> identityLinksForTask = taskService.getIdentityLinksForTask(taskId);
//                        Set<String> userIds = new HashSet<>();
//                        for (IdentityLink identityLink : identityLinksForTask) {
//                            String userId = identityLink.getUserId();
//                            userIds.add(userId);
//                        }
//                        List<String> messageType = new ArrayList<>();
//                        messageType.add(MessageTypeEnum.SysMessage.getCode());
//                        SentMessageForm sentMessageForm = new SentMessageForm();
//                        sentMessageForm.setSendType(messageType);
//                        Map<String, Object> messageInfo = new HashMap<>(16);
//                        messageInfo.put("type", FlowMessageEnum.dueDate.getCode());
//                        messageInfo.put("id", processInstanceId);
//                        sentMessageForm.setContent(JsonUtilEx.getObjectToString(messageInfo));
//                        sentMessageForm.setTitle(title + "【这条审批已经超时了,请您及时处理!】");
//                        sentMessageForm.setToUserIds(new ArrayList<>(userIds));
//                        Map<String, String> smsContent = new HashMap<>(16);
//                        this.message(title, title, smsContent);
//                        sentMessageForm.setSmsContent(smsContent);
//                        //拿到节点上的人发通知:
//                        sentMessageUtil.sendMessage(sentMessageForm);
                    }
                }
            }*/


        }

    }

    /**
     * 短信模板
     *
     * @param title  标题
     * @param status 状态
     * @return
     */
    private void message(String title, String status, Map<String, String> msg) {
        Map<String, String> aliyun = new HashMap<>(16);
        aliyun.put("title", title);
        aliyun.put("status", status);
        msg.put("1", JsonUtil.getObjectToString(aliyun));
        msg.put("2", "2");
    }

}
